﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using MovieModel.Model.Common;
using MovieModel.Search;
using KewlStuff.Extensions;

namespace MovieModel.Model
{
    public class Movie : ImageMovieItem<Movie>
    {
        public IEnumerable<MoviePart> People { get; internal set; }
        public IEnumerable<Company> Companies { get; internal set; }
        public IEnumerable<Tag> Tags { get; internal set; }
        public int? Year { get; internal set; }
        public int? Runtime { get; internal set; }
        public string Description { get; internal set; }
        public FileInfo MovieFile { get; internal set; }

        public event EventHandler<ItemUpdatedEventArgs<Movie>> PlayCountUpdated;

        public void InvokePlayCountUpdated()
        {
            EventHandler<ItemUpdatedEventArgs<Movie>> handler = PlayCountUpdated;
            if (handler != null) handler(this, new ItemUpdatedEventArgs<Movie>(this));
        }

        private int? playCount;
        public int? PlayCount
        {
            get { return playCount; }
            set
            {
                if (playCount != PlayCount)
                {
                    playCount = value;
                    InvokePlayCountUpdated();
                }
            }
        }

        protected override bool SubMatches(SearchQuery query)
        {
            return Tags.Any(t => t.Matches(query)) ||
                   Companies.Any(c => c.Matches(query)) ||
                   People.Any(p => p.Person.Matches(query));
        }

        public override bool Matches(SearchQuery query)
        {
            if (query.IsBlank) return true;
            return
                (query.Tags == null || query.Tags.Intersect(Tags).Any()) &&
                (query.Free == null || query.Free.Any(s => Description.ContainsIgnoreCase(s)) || base.Matches(query)) &&
                (query.People == null || query.People.Intersect(People.Select(mp => mp.Person)).Any());
        }

        public static Movie CreateNewMovie(string name)
        {
            return new Movie {Name = name};
        }

        public void Update(
            string name,
            string thumbnailLocation,
            string imageLocation,
            int? year, 
            int? runtime, 
            string description, 
            IEnumerable<Tag> tags, 
            IEnumerable<Company> companies,
            IEnumerable<MoviePart> people,
            FileInfo movieFile)
        {
            Name = name;
            ThumbnailLocation = thumbnailLocation;
            ImageLocation = imageLocation;
            Year = year;
            Runtime = runtime;
            Description = description;
            Tags = tags;
            Companies = companies;
            People = people;
            MovieFile = movieFile;
            InvokeItemUpdated();
        }
    }
}
